package com.paradogs.generator;

import com.alibaba.excel.EasyExcel;
import com.paradogs.framework.core.utils.StringUtils;
import com.paradogs.generator.misc.ExcelDataGeneratorListener;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.*;

/**
 * @author: yumi
 * @date: 2023/12/5  21:58
 * @Description: 配置表实体类生成器
 */
@Slf4j
public class ExcelDataGenerator {

    public static void main(String[] args) throws IOException, TemplateException {
        String path = System.getProperty("user.dir") + "/paradogs-framework/paradogs-framework-common/src/main/resources/data";
        File folder = new File(path);

        for (File file : folder.listFiles()) {
            ExcelDataGeneratorListener reader = new ExcelDataGeneratorListener();
            EasyExcel.read(file, reader)
                    .headRowNumber(0) // 表头也读取
                    .sheet(0)
                    .doRead();
            String fileDataName = StringUtils.firstChar2UpperCase(file.getName().substring(0, file.getName().lastIndexOf("(")));

            // 创建 Freemarker 配置
            Configuration cfg = new Configuration(new Version("2.3.31"));
            cfg.setClassLoaderForTemplateLoading(ExcelDataGenerator.class.getClassLoader(), "ftls");
            cfg.setDefaultEncoding("UTF-8");

            // 加载模板
            Template template = cfg.getTemplate("data.ftl");

            // 创建数据模型
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("package", "com.paradogs.framework.common.data");

            List<LinkedHashMap<Integer, String>> dataMaps = reader.getData();
            if (dataMaps.size() < 2) {
                log.error("{} row < 2", file.getName());
                continue;
            }

            // 生成数据项
            List<Map<String, String>> dataFields = new ArrayList<>(); // 数据项
            List<Map<String, String>> configFields = new ArrayList<>(); // -1 项
            List<Map<String, String>> templateFields = new ArrayList<>(); // 模板：包含数据项和 -1 项所有字段
            Map<Integer, String> descList = dataMaps.get(0);
            Map<Integer, String> paramAndTypeList = dataMaps.get(1);
            for (Map.Entry<Integer, String> entry : paramAndTypeList.entrySet()) {
                Integer index = entry.getKey();
                String val = entry.getValue().trim();
                String[] split = val.split(":");
                if (split.length != 2) {
                    log.error("{} error type format, need paramName:type(exp:number)");
                    continue;
                }
                // 添加数据项的字段列，至少有一行有此列的值则生成
                boolean dataHasVal = false;
                for (int i = 3; i < dataMaps.size(); i++) {
                    LinkedHashMap<Integer, String> row = dataMaps.get(i);
                    if (row != null && StringUtils.isNotBlank(row.get(index))) {
                        dataHasVal = true;
                        break;
                    }
                }
                String paramName = split[0].trim();
                String typeName = split[1].trim();
                // 待优化：枚举策略
                String type = "Object";
                if (typeName.equalsIgnoreCase("number")) {
                    if (typeName.indexOf(".") != -1) {
                        type = "Double";
                    } else {
                        type = "Long";
                    }
                } else if (typeName.equalsIgnoreCase("number[]")) {
                    type = "Long[]";
                }
                else if (typeName.equalsIgnoreCase("string")) {
                    type = "String";
                }
                // 添加生成属性
                if (dataHasVal) {
                    dataFields.add(createField(type, paramName, descList.get(index)));
                }

                // 添加 -1 项的列：约定第三行为 -1 项，第一列为 id
                LinkedHashMap<Integer, String> configRow = dataMaps.get(2);
                if (StringUtils.isNotBlank(configRow.get(index))) {
                    configFields.add(createField(type, paramName, descList.get(index)));
                }

                templateFields.add(createField(type, paramName, descList.get(index)));


            }
            dataModel.put("dataFields", dataFields);
            dataModel.put("configFields", configFields);
            dataModel.put("templateFields", templateFields);

            dataModel.put("package", "com.paradogs.framework.common.data");
            dataModel.put("utilsPackage", "com.paradogs.framework.common.utils");
            dataModel.put("className", fileDataName);
            dataModel.put("innerDataName", "Data");
            dataModel.put("innerConfigName", "Config");
            dataModel.put("filePath", file.getAbsolutePath().replace("\\", "/"));
            dataModel.put("fileDesc", file.getName());

            // 指定输出文件路径
            String outputFilePath = System.getProperty("user.dir")
                    + "/paradogs-framework/paradogs-framework-common/src/main/java/com/paradogs/framework/common/data/"
                    + fileDataName
                    + ".java";

            File outputFile = new File(outputFilePath);

            // 确保输出目录存在
            outputFile.getParentFile().mkdirs();

            // 使用 FileWriter 将生成代码写入到文件
            try (Writer fileWriter = new BufferedWriter(new FileWriter(outputFile))) {
                template.process(dataModel, fileWriter);
            }

        }

    }

    private static Map<String, String> createField(String type, String name, String description) {
        Map<String, String> field = new HashMap<>();
        field.put("type", type);
        field.put("name", name);
        field.put("description", description);
        return field;
    }
}
